﻿using System;

namespace bank
{
    // 坏钞异常
    public class BadCashException : Exception
    {
        public BadCashException(string message) : base(message) { }
    }

    // 大额取款事件参数
    public class BigMoneyArgs : EventArgs
    {
        public Account Account { get; }
        public decimal Amount { get; }

        public BigMoneyArgs(Account account, decimal amount)
        {
            Account = account;
            Amount = amount;
        }
    }

    // 账号基类
    public class Account
    {
        // 字段
        private string _accountNumber;
        private decimal _balance;

        // 属性
        public string AccountNumber
        {
            get { return _accountNumber; }
            private set { _accountNumber = value; }
        }

        public decimal Balance
        {
            get { return _balance; }
            protected set { _balance = value; }
        }

        // 构造函数
        public Account(string accountNumber, decimal initialBalance)
        {
            AccountNumber = accountNumber;
            Balance = initialBalance;
        }

        public virtual void Deposit(decimal amount)
        {
            if (amount <= 0)
                throw new ArgumentException("存款金额必须大于0。");

            Balance += amount;
            Console.WriteLine($"存款成功：{amount}元，当前余额：{Balance}元");
        }

        public virtual void Withdraw(decimal amount)
        {
            if (amount <= 0)
                throw new ArgumentException("取款金额必须大于0。");

            if (amount > Balance)
                throw new InvalidOperationException("余额不足。");

            Balance -= amount;
            Console.WriteLine($"取款成功：{amount}元，当前余额：{Balance}元");
        }
    }

    // 信用账号子类
    public class CreditAccount : Account
    {
        // 新增字段：信用额度
        private decimal _creditLimit;

        // 新增属性：信用额度
        public decimal CreditLimit
        {
            get { return _creditLimit; }
            private set { _creditLimit = value; }
        }

        // 构造函数
        public CreditAccount(string accountNumber, decimal initialBalance, decimal creditLimit)
            : base(accountNumber, initialBalance)
        {
            CreditLimit = creditLimit;
        }

        // 重写取款方法：支持信用额度
        public override void Withdraw(decimal amount)
        {
            if (amount <= 0)
                throw new ArgumentException("取款金额必须大于0。");

            if (amount > Balance + CreditLimit)
                throw new InvalidOperationException("超出信用额度。");

            Balance -= amount;
            Console.WriteLine($"取款成功：{amount}元，当前余额：{Balance}元，剩余信用额度：{CreditLimit + Balance}元");
        }
    }

    // ATM类
    public class ATM
    {       
        public event EventHandler<BigMoneyArgs> BigMoneyFetched;
        public void Withdraw(Account account, decimal amount)
        {
            try
            {
                // 模拟坏钞率30%
                if (new Random().Next(1, 101) <= 30)
                    throw new BadCashException("发现坏钞，取款失败！");

                account.Withdraw(amount);

                // 触发大额取款事件
                if (amount > 10000)
                    BigMoneyFetched?.Invoke(this, new BigMoneyArgs(account, amount));
            }
            catch (BadCashException ex)
            {
                Console.WriteLine($"取款失败：{ex.Message}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"取款失败：{ex.Message}");
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            // 创建账号
            Account myAccount = new Account("123456789", 5000);
            CreditAccount myCreditAccount = new CreditAccount("987654321", 1000, 5000);

            // 创建ATM
            ATM atm = new ATM();

            // 注册大额取款事件
            atm.BigMoneyFetched += (sender, e) =>
            {
                Console.WriteLine($"警告：账户 {e.Account.AccountNumber} 取款 {e.Amount} 元，请注意资金安全！");
            };

            // 操作ATM
            Console.WriteLine("--- 普通账号操作 ---");
            atm.Withdraw(myAccount, 2000); // 正常取款
            atm.Withdraw(myAccount, 12000); // 触发大额取款事件

            Console.WriteLine("\n--- 信用账号操作 ---");
            atm.Withdraw(myCreditAccount, 3000); // 使用信用额度取款
            atm.Withdraw(myCreditAccount, 7000); // 超出信用额度

            Console.WriteLine("\n--- 模拟坏钞情况 ---");
            atm.Withdraw(myAccount, 1000); // 模拟坏钞
        }
    }
}